// File Name: rs485_ctrl.c
// Author: kukukukuku~
// Date: 2024-12-20

#include "apm32f00x_gpio.h"
#include "apm32f00x_usart.h"
#include "./RS485/inc/rs485_ctrl.h"

/**
 * @brief   CRC16-MODBUS算法
 * @param   data:       数据源
 * @param   dataLen:    数据个数
 * @retval  计算结果
 * @note    None
*/
uint16_t rs485_crc16_modbus_calc(const uint8_t * const data, const uint16_t dataLen)
{
    uint16_t crcInit = 0xFFFF;
    uint16_t crcPoly = 0xA001;
    uint16_t crcVal = crcInit;
    
    if(data == NULL || dataLen == 0)
        return 0;
    
    for(uint16_t i = 0; i < dataLen; i++)
    {
        crcVal ^= data[i];
        
        for(uint8_t j = 0; j < 8; j++)
        {
            crcVal & 0x0001 ?
            (crcVal = (crcVal>>1) ^ crcPoly) :
            (crcVal >>= 1);
        }
    }
    
    return crcVal;
}


/**
 * @brief   RS485串口发送数据
 * @param   data:       数据源
 * @param   dataLen:    数据个数
 * @retval  None
 * @note    None
*/
void rs485_usart_send_data(const uint8_t * const data, const uint16_t dataLen)
{
    if(data == NULL || dataLen == 0)
        return;
    
    for(uint16_t i = 0; i < dataLen; i++)
    {
        while(!USART_ReadStatusFlag(RS485_USART, USART_FLAG_TXC));
        USART_TxData8(RS485_USART, data[i]);
    }
    
    while(!USART_ReadStatusFlag(RS485_USART, USART_FLAG_TXC));
}


/**
 * @brief   RS485串口接收数据
 * @param   None
 * @retval  接收到的数据
 * @note    None
*/
uint8_t rs485_usart_receive_data(void)
{
    return USART_RxData8(RS485_USART);
}


/**
 * @brief   RS485设置模式
 * @param   mode:   模式
 * @retval  None
 * @note    None
*/
void rs485_set_mode(const RS485_MODE_T mode)
{
    mode == RS485_MODE_RECEIVE ? (RS485_SET_MODE_TO_RECEIVE) : (RS485_SET_MODE_TO_SEND);
}
